package com.dream.base.web.service.impl;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.Executor;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.fileupload.FileUpload;
import org.apache.commons.fileupload.ProgressListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import com.dream.app.cache.ProgressCache;
import com.dream.base.web.service.FileUploadService;
import com.dream.model.app.AppAbstractUser;
import com.dream.utils.log.DreamLogUtils;
import com.dream.utils.system.cfg.SystemConfigUtils;
import com.dream.vo.base.Constants;

@Service("FileUploadService")
public class FileUploadServiceImpl implements  FileUploadService{
	
	@Resource(name="fileUploadExecutor")
	private Executor fileUploadExecutor;
	
	private static final Long FILE_MAX_SIZE;
	static{
		FILE_MAX_SIZE = SystemConfigUtils.instance().getLong("system.file.upload.maxsize", 536870912L);
	}
	@Autowired
	private ProgressCache progressCache;
	
	@Transactional
	@Override
	public void uploadFile(final MultipartFile file, final String folderPath,final String filePath) {
		
		File folder = new File(folderPath);
		if (!folder.exists()) {
			folder.mkdirs();
		}
		if(file != null ){
			try {
				file.transferTo(new File(filePath));
			} catch (IllegalStateException e) {
				DreamLogUtils.error("FileUploadUtils", "IllegalStateException", "IOException", e);
				throw new RuntimeException(e);
			} catch (IOException e) {
				DreamLogUtils.error("FileUploadUtils", "uploadFile", "IOException", e);
				throw new RuntimeException(e);
			}
		}
		
	}



	@Override
	@Transactional
	public  MultipartFile getUploadedFileInfo(final HttpServletRequest httpRequest,final String fileId){
		
		CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver(
				httpRequest.getSession().getServletContext());

		// 设置编码 FileUpload的文件编码与CommonsMultipartResolver编码必须一样
		FileUpload loader = commonsMultipartResolver.getFileUpload();
		loader.setHeaderEncoding(FILE_ENCODING);
		commonsMultipartResolver.setDefaultEncoding(FILE_ENCODING);
		commonsMultipartResolver.setMaxUploadSize(FILE_MAX_SIZE);
		commonsMultipartResolver.setMaxInMemorySize(1048576);
		
		// 绑定文件上传监听器
		HttpSession session = httpRequest.getSession(false);
		AppAbstractUser user = (AppAbstractUser)session.getAttribute(Constants.USER_ID);
		String key = user.getId().concat(fileId);
		
		ProgressListener listener = new UploadProgressListener(key,progressCache);
		loader.setProgressListener(listener);
		
		// 判断 request 是否是多部分请求
		MultipartFile file = null;
		if (commonsMultipartResolver.isMultipart(httpRequest)) {
			// 转换成多部分request
			 MultipartHttpServletRequest multipartRequest = commonsMultipartResolver.resolveMultipart(httpRequest);     
			// 根据 name获取上传的文件
			file = multipartRequest.getFile(fileId);
		}
		return file;
	}



	@Override
	@Transactional
	public void uploadFileAsy(final MultipartFile file, final String folderPath,final String filePath) {
		
		fileUploadExecutor.execute(new Runnable(){

			@Override
			public void run() {
				uploadFile(file,folderPath,filePath);
			}
		});
	}
	
	
}
